package com.xiguaji.tiktok.utils.jwt;

import com.xiguaji.boot.toolkit.DateUtil;
import com.xiguaji.boot.toolkit.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.jwt.crypto.sign.MacSigner;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Date;


@Slf4j
@Component
public class JwtUtil {

    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expiration}")
    private Long accessTokenExpiration;

    private MacSigner signer;

    @PostConstruct
    private void postConstruct(){
        signer = new MacSigner(secret);
    }

    /**
     * 解密并获取claims
     * @param token
     * @return
     */
    private String getClaimsFromToken(String token){
        Jwt jwt = JwtHelper.decodeAndVerify(token, signer);
        return jwt.getClaims();
    }

    /**
     * 生成token
     * @param jwtUser
     * @return
     */
    public String generaToken(JwtUser jwtUser){
        Date date = new Date();
        Date expiredDate = DateUtil.addSecond(date,accessTokenExpiration);
        Date refreshDate = DateUtil.addSecond(date,accessTokenExpiration-60*10);
        jwtUser.setExpiration(expiredDate);
        jwtUser.setRefresh(refreshDate);
        String json = JsonUtil.parseJson(jwtUser);
        Jwt jwt = JwtHelper.encode(json, signer);
        return jwt.getEncoded();

    }

    public JwtUser getJwtUserByToken(String token){
        String json = getClaimsFromToken(token);
        return JsonUtil.jsonParse(JwtUser.class,json);
    }

    private Boolean isExpired(JwtUser jwtUser){
        return jwtUser.getExpiration().before(new Date());
    }

    private Boolean isRefresh(JwtUser jwtUser){
        return jwtUser.getExpiration().before(new Date());
    }

    public Boolean isRefresh(String token) {
        JwtUser jwtUser = getJwtUserByToken(token);
        return isRefresh(jwtUser);
    }


    public Boolean validateToken(String token){
        JwtUser jwtUser = getJwtUserByToken(token);
        if(isExpired(jwtUser)){
            log.debug("{}:已过期",token);
            return false;
        }
        return true;
    }

    /**
     * 验证token并刷新token
     * @param token
     * @return
     */
    public String refreshToken(String token){
        if(validateToken(token)){
            JwtUser jwtUser = getJwtUserByToken(token);
            if(isRefresh(jwtUser)){
                return generaToken(jwtUser);
            }
            return token;
        }
        return null;
    }

    /**
     * 获取对象
     * @param token
     * @return
     */
    public JwtUser getJwtUser(String token){
        if(validateToken(token)){
            return getJwtUserByToken(token);
        }
        return null;
    }
}
